package com.tsinghua.server.common.utils;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ExcleUtil {

    /**
     * 导入excle数据
     * @param file 文件
     * @param headerRows 忽略头行数
     * @param pojoClass 转换的实体
     * @param <T> 返回的集合
     * @return
     */
    public static <T> List<T> importData(MultipartFile file, Integer headerRows,
                                         Class<T> pojoClass) {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setHeadRows(headerRows);
        params.setNeedVerify(false);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 导出excel表格
     * @param list 导出的数据
     * @param title 文件标题
     * @param sheetName sheet名称
     * @param pojoClass 集合对应的pojo类
     * @param fileName 文件名
     * @param response 响应对象
     */
    public static void exportExcel(List<?> list, String title, String sheetName,
                                   Class<?> pojoClass, String fileName, HttpServletResponse response) {
        /**
         * 工作簿 对象
         * Workbooks 集合包含 Microsoft Excel 中当前打开的所有 Workbook 对象。
         *
         * workbook分别有HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook
         * HSSFWorkbook：针对EXCEL 2003版本，扩展名为.xls，此种的局限就是导出的行数最多为65535行。因为导出行数受限，不足7万行，所以一般不会发送内存溢出(OOM)的情况
         *
         * *** XSSFWorkbook：由于第一种HSSF的局限性产生的，因为其导出行数较少，XSSFWorkbook应运而生，其对应的是EXCEL2007+ ，
         * 扩展名为.xlsx ，最多可以导出104万行，不过这样就伴随着一个问题–OOM内存溢出。
         * 因为使用XSSFWorkbook创建的book sheet row cell 等是存在内存中的，并没有持久化到磁盘上，
         * 那么随着数据量的增大，内存的需求量也就增大。
         *
         * SXSSFWorkbook：SXSSFWorkbook可以根据行数将内存中的数据持久化写到文件中。
         * 此种的情况就是设置最大内存条数，比如设置最大内存量为5000行， new SXSSFWookbook(5000)，
         * 当行数达到 5000 时，把内存持久化写到文件中，以此逐步写入，避免OOM。这样就完美解决了大数据下导出的问题
         */
        Workbook workbook =  getWorkbook(sheetName,pojoClass,list);   // ExcelExportUtil.exportBigExcel(new ExportParams(title, sheetName), pojoClass, list);
        System.out.println(workbook.toString());
        if (workbook != null) {
            try {
                // 设置响应编码
                response.setCharacterEncoding("UTF-8");
                // 设置响应头 导出文件类型 导出文件名 等
                response.setHeader("content-Type", "application/vnd.ms-excel");
                response.setHeader("Content-Disposition", "attachment;filename=" +
                        new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
                // 写入文件流
                workbook.write(response.getOutputStream());
            //    ExcelExportUtil.closeExportBigExcel();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }





    /**
     *
     */
    private static final Integer EXPORT_EXCEL_MAX_NUM = 20000;

    /**
     * 获取导出的Workbook对象
     *
     * @param sheetName 页签名
     * @param clazz     类对象
     * @param list      导出的数据集合
     * @return
     * @author xiagwei
     * @date 2020/2/10 4:45 PM
     */
    public static Workbook getWorkbook(String sheetName, Class clazz, List<?> list) {
        //获取导出参数
        ExportParams exportParams = new ExportParams();
        //设置sheetName
        exportParams.setSheetName(sheetName);
        //输出workbook流
        return ExcelExportUtil.exportExcel(exportParams, clazz, list);
    }


}
